# coding=utf-8
from __future__ import print_function, absolute_import
from gm.api import *
import talib

def init(context):
    context.short = 20                                       # 短周期均线
    context.long = 60                                        # 长周期均线
    context.symbol = 'SZSE.000001'                           # 订阅交易标的
    context.period = context.long + 100                        # 订阅数据滑窗长度
    context.open_long = False                                # 开多单标记
    context.open_short = False                               # 开空单标记
    subscribe(symbols= context.symbol, frequency='1d', count=context.period) # 订阅行情
    
def on_bar(context, bars):
    # 获取通过subscribe订阅的数据,context.data 函数用于获取市场数据。
    data =context.data(symbol=context.symbol, frequency='1d', count=context.period, fields='close')

    # 利用talib库计算长短周期均线
    short_avg  = data['close'].rolling(context.short).mean()
    long_avg  = data['close'].rolling(context.long).mean()


    # 获取现有持仓
    pos = list(filter(lambda x:x['symbol']==context.symbol,get_position()))

    # 短均线下穿长均线，做空(即当前时间点短均线处于长均线下方，前一时间点短均线处于长均线上方)
    if pos and long_avg.values[-2] < short_avg.values[-2] and long_avg.values[-1] >= short_avg.values[-1]:

        order_volume(symbol=context.symbol, volume=100, side=OrderSide_Sell,
                        order_type=OrderType_Limit, position_effect=PositionEffect_Close, price=data.close.values[-1])

    elif not pos and short_avg.values[-2] < long_avg.values[-2] and short_avg.values[-1] >= long_avg.values[-1]:

        order_volume(symbol=context.symbol, volume=100, side=OrderSide_Buy,
                        order_type=OrderType_Limit, position_effect=PositionEffect_Open, price=data.close.values[-1])

def on_order_status(context, order):
    # 标的代码
    symbol = order['symbol']
    # 委托价格
    price = order['price']
    # 委托数量
    volume = order['volume']
    # 目标仓位
    target_percent = order['target_percent']
    # 查看下单后的委托状态，等于3代表委托全部成交
    status = order['status']
    # 买卖方向，1为买入，2为卖出
    side = order['side']
    # 开平仓类型，1为开仓，2为平仓
    effect = order['position_effect']
    # 委托类型，1为限价委托，2为市价委托
    order_type = order['order_type']
    if status == 3:
        if effect == 1:
            if side == 1:
                side_effect = '开多仓'
            else:
                side_effect = '开空仓'
        else:
            if side == 1:
                side_effect = '平空仓'
            else:
                side_effect = '平多仓'
        order_type_word = '限价' if order_type==1 else '市价'
        print('{}:标的：{}，操作：以{}{}，委托价格：{}，委托数量：{}'.format(context.now,symbol,order_type_word,side_effect,price,volume))


def on_backtest_finished(context, indicator):
    print('*'*50)
    print('回测已完成，请通过右上角“回测历史”功能查询详情。')


if __name__ == '__main__':
    '''
        strategy_id策略ID,由系统生成
        filename文件名,请与本文件名保持一致
        mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST
        token绑定计算机的ID,可在系统设置-密钥管理中生成
        backtest_start_time回测开始时间
        backtest_end_time回测结束时间
        backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
        backtest_initial_cash回测初始资金
        backtest_commission_ratio回测佣金比例
        backtest_slippage_ratio回测滑点比例
        backtest_match_mode市价撮合模式，以下一tick/bar开盘价撮合:0，以当前tick/bar收盘价撮合：1
    '''
    run(strategy_id='dd40e01f-3dd6-11ef-95a4-3417eb91badb',
        filename='main.py',
        mode=MODE_BACKTEST,
        token='bf739ec28ad507f391a3c3e99ed0365007da88f8',
        backtest_start_time='2024-01-01 08:00:00',
        backtest_end_time='2024-7-31 15:30:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=1000000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001,
        backtest_match_mode=1)